#pragma once 
#include <ctime>
#include <time.h>
#include <string>
#include <Windows.h>
#include <assert.h>
using namespace std;

#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#include <dxerr.h>
#pragma comment(lib, "dxerr.lib")
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")


#ifdef _DEBUG
#ifndef HR

#define HR(x)					\
{								\
	HRESULT hr = x;				\
	if (FAILED(hr))				\
{							\
	DXTRACE_ERR(#x, hr);	\
	DebugBreak();			\
}							\
}
#endif
#else
#ifndef HR
#define HR(x) x;
#endif
#endif

const unsigned int SCREEN_WIDTH	 = 1024;
const unsigned int SCREEN_HEIGHT = 768;
static int GameState;
static int PlayerTurn;

 
/*Indicates Mesh, Texture and Behavior*/
enum e3DOBJECT_IDS
{
	D3OBJ_EMPTY,	//-0
	D3OBJ_BOUNDARY, //-1
	D3OBJ_CHIT,		//-2
	D3OBJ_ARROW,
	D3OBJ_LASER,	//-3
	D3OBJ_PYRAMID,	//-4
	D3OBJ_SCARAB,	//-5
	D3OBJ_SPHINX,	//-6
	D3OBJ_ANUBIS,	//-7
	D3OBJ_PHARAOH,	//-8
	D3OBJ_SIZE		//-9
};
/*Indicates Texture and Behavior*/
enum e2DOBJECT_IDS
{
	TEX_BUTTON,
	TEX_MENUPANE,
	TEX_SPLASH,
	TEX_SIZE
};
/*Possible XY Moves*/
enum eDIRECTIONS
{
	DIR_NORTH,
	DIR_EAST,
	DIR_SOUTH,
	DIR_WEST,
	DIR_SIZE
};
/*Possible game conditions*/
enum MENU_STATES
{
	ST_PLAY,
	ST_PAUSED,
	ST_OPTIONS,
	ST_GAMEWON1,
	ST_GAMEWON2,
	ST_VALIDATE,
	ST_LASER,
	ST_MAIN,
	ST_RESET,
	ST_QUIT,
	ST_SIZE
};
/*Player Alignment*/
enum PLAYERS
{
	Neutral,
	Player1,
	Player2,
	PLAY_SIZE
};
/*For setting events on a timer*/

class Timer		
{
private:

	double TimeAtNow;		//Current time in MS
	double	TimeAtThen;		//Last time in MS			
	double  DeltaT;			//The difference between
	double	ElapsedT;		//Time elapsed since last time accessed

	void SetTimer()				
	{
		//DeltaT = 0;
		//QueryPerformanceCounter((LARGE_INTEGER*)&TimeAtThen);
	}
	Timer()								
		:DeltaT(NULL),
		TimeAtNow(0),
		TimeAtThen(0)
	{
		SetTimer();
	}

public:

	static Timer* Into()	//Returns pointer to the singleton instance
	{
		static Timer Timer;
		return &Timer;
	}
	void Init()
	{
		TimeAtNow = ::timeGetTime() * 0.0001;
		TimeAtThen = TimeAtNow;
		DeltaT = TimeAtNow - TimeAtThen;
		ElapsedT = DeltaT;
	}
	void Update()
	{
		TimeAtNow = ::timeGetTime() * 0.001;
		DeltaT = TimeAtNow - TimeAtThen;
		ElapsedT += DeltaT;
		TimeAtThen = TimeAtNow;
	}
	double GetDTime()
	{
		return DeltaT;
	}
	bool Wait(double limit)
	{
		if(ElapsedT > limit)
		{
			ElapsedT = 0.0;
			return true;
		}
		return false;
	}
};
/*For XY or XZ Coordinates*/
struct Pair
{
	float X,Y;
	Pair():X(0),Y(0){};
	Pair(float x, float y):X(x),Y(y){};
};